namespace Serialization
{
    using System;
using System.Collections.Generic;
    
    public class SurrogateSelector : ISurrogateSelector
    {
        private ISurrogateSelector _nextSelector;
        private Dictionary<Type, ISerializationSurrogate> _surrogates = new Dictionary<Type, ISerializationSurrogate>(0x20);

        public virtual void AddSurrogate(Type type, ISerializationSurrogate surrogate)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }
            if (surrogate == null)
            {
                throw new ArgumentNullException("surrogate");
            }
            _surrogates.Add(type, surrogate);
        }

        public virtual void ChainSelector(ISurrogateSelector selector)
        {
            if (_nextSelector == null)
            {
                _nextSelector = selector;
            }
            else
            {
                _nextSelector.ChainSelector(selector);
            }
        }

        public virtual ISurrogateSelector GetNextSelector()
        {
            return _nextSelector;
        }

        public virtual ISerializationSurrogate GetSurrogate(Type type, out ISurrogateSelector selector)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }
            selector = this;
            ISerializationSurrogate surrogate;
            if(_surrogates.TryGetValue(type, out surrogate))
            {
                return surrogate;
            }
            if (_nextSelector != null)
            {
                return _nextSelector.GetSurrogate(type, out selector);
            }
            return null;
        }

        public virtual void RemoveSurrogate(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }
            _surrogates.Remove(type);
        }
    }
}

